import xPivotData from './xPivotData.js';
import xFilter from "./xFilter.js";
import {replaceByObj} from "./xUtil.js";
import {jsonToCsv, saveAsCsv, saveAsXmlXls} from "./xUtil.js";
import xmlTable from "./xmlTable.js";
import xID from './xID.js';
import cell from "./cell.js";
/*
 */

const tmplBase =`<div class="{{class}}">
                   <table>
                       <thead ></thead>
                       <tbody ></tbody>
                   </table>
                   <div type="filter-panel" style="position: absolute;z-index:100; display: none"></div>              
                 </div>`;

const tmplTd ='<td {{colspan}} {{rowspan}} type="{{type}}">{{html}}</td>';
const tmplTr= '<tr>{{html}}</tr>';


export default class xPivot{
    $root;
    $table;
    $head;
    $body;
    vPivotId =xID.getID();
    vCfg;
    vPivotData = new xPivotData();
    vFilter;


    /*定义变量 结束*/
    // 构造函数
    constructor(cfg) {
        this.vCfg =cfg;
        this.$root = $('#' + cfg.el);
        this.$root.html(replaceByObj(tmplBase,{class:cfg.style|| 'pivot'}));
    };

    refresh(){
        this.vPivotData.prepare(this.vCfg);
        this.renderPivot();
    }

    init(){
        this.$table = this.$root.find('table');
        this.$head = this.$root.find('thead');
        this.$body = this.$root.find('tbody');
        this.vFilter = new xFilter(this.$root.find('[type="filter-panel"]'));
        this.$root.on('click', 'i[type="filter"]', this.evFilter.bind(this));
        this.$root.on('click', '[type="V"]', this.evValueClick.bind(this));
        this.$root.on('click', '[type="Y"]', this.evYClick.bind(this));
        this.$root.on('click', '[type="X"]', this.evXClick.bind(this));
        this.refresh();
    }


    //{{style}} {{dataKey}} {{dataCode}} >{{item}}
    //const tmplItemStyle ='class ="{{align}} {{style}}"';

    renderTd(item,key,type,pos){
        //let factor = type=='X'?this.vCfg.values.length:1;
        //span factor 要根据 type  和 valuesOn 来判断;
        let factor =this.vCfg.values.length;
        let colspan = (item && item._colspan)?item._colspan:1;
        let rowspan = (item && item._rowspan)?item._rowspan:1;
        //let html = this.renderPivotCell(item,key,type,pos);
        let html = '';
        let cfg = {item,key,type,pos};
        switch(type){
            case 'X':
                if(!(this.vCfg.valuesOn =='Y'))
                    colspan = colspan*factor;
                html = cell.renderPivotXCell(cfg);
                break;
            case 'Y':
                if(this.vCfg.valuesOn =='Y')
                    rowspan = rowspan*factor;
                html = cell.renderPivotYCell(cfg);
                break;
            case 'V':
                html = cell.renderPivotVCell(cfg);
                break;
            case 'YTitle':
                cfg.filterActive = this.vPivotData.isActiveFilter(key.$code)
                html = cell.renderPivotYTitle(cfg);
                break;
            case 'VTitle':
                html = cell.renderPivotVTitle(cfg);
                break;
            case 'XTitle':
                cfg.filterActive = this.vPivotData.isActiveFilter(key.$code)
                html = cell.renderPivotXTitle(cfg);
                break;
        }
        return replaceByObj(tmplTd,{colspan:colspan==1?'':'colspan="'+colspan+'"',
             rowspan:rowspan==1?'':'rowspan="'+rowspan+'"',html,type});
    }

    renderTitle(){
        let tds ='';
        for(let y of this.vCfg.keysY){
            tds += this.renderTd({_colspan:1,_rowspan:1},y,'YTitle')
        }

        for(let i=0;i<this.vPivotData.vAxisX.length;i++){
            this.vCfg.values.forEach((key) =>
                tds += this.renderTd({},key,'VTitle'))
        }
        return tmplTr.replace('{{html}}',tds);
    }

    renderXTitle(i){
        return   this.renderTd({_colspan:this.vCfg.keysY.length,
            _rowspan:1},this.vCfg.keysX[i],'XTitle');

    }


    renderX(){
        let trs ='';
        let tds;
        for(let i in this.vPivotData.vAxisXMatrix){
            tds = this.renderXTitle(i);
            for(let j in this.vPivotData.vAxisXMatrix[i]){
                let item = this.vPivotData.vAxisXMatrix[i][j];
                if(item){
                    tds += this.renderTd(item,null,'X');
                }
            }
            trs += tmplTr.replace('{{html}}',tds);
        }
        return trs + this.renderTitle();
    }

    renderY(i){
        let tds = '';
        for(let j in this.vPivotData.vAxisYMatrix[i]){
            let item = this.vPivotData.vAxisYMatrix[i][j];
            tds += this.renderTd(item,null,'Y')
        }
        return tds;
    }

    renderYV(){
        let trs ='';
        let tds;
        for(let i=0;i<this.vPivotData.vAxisY.length;i++){
            tds = this.renderY(i);
            for(let j=0;j<this.vPivotData.vAxisX.length;j++){
                let item = this.vPivotData.vDataMatrix[i][j];
                this.vCfg.values.forEach((key,index) =>{
                    let pos = j+','+i+','+index;
                    tds += this.renderTd(item,key,'V',pos)
                })
            }
            trs += tmplTr.replace('{{html}}',tds);
        }
        return trs;
    }

    /*数据列 在 Y 上的情况*/
    renderXOnY(){
        let trs ='';
        let tds;
        for(let i=0;i<this.vPivotData.vAxisXMatrix.length;i++){
            tds ='';
            if(i==0){
                tds += this.renderYTitleOnY();
            }
            tds += this.renderXTitleOnY(i);
            for(let j in this.vPivotData.vAxisXMatrix[i]){
                let item = this.vPivotData.vAxisXMatrix[i][j];
                if(item){
                    tds += this.renderTd(item,null,'X');
                }
            }
            trs += tmplTr.replace('{{html}}',tds);
        }
        return trs;
    }

    renderYOnY(i){
        let tds = '';
        for(let j in this.vPivotData.vAxisYMatrix[i]){
            let item = this.vPivotData.vAxisYMatrix[i][j];
            if(item)
                tds += this.renderTd(item,null,'Y')
        }
        return tds;
    }

    renderYTitleOnY(){
        let tds ='';
        for(let y of this.vCfg.keysY){
            tds += this.renderTd({_colspan:1,_rowspan:this.vCfg.keysX.length},
                y,'YTitle')
        }
        return tds;
    }

    renderXTitleOnY(i){
        return   this.renderTd({_colspan:1,
            _rowspan:1},this.vCfg.keysX[i],'XTitle')
    }
    /*
    *  数据行放在 列上的  先 取 Y 上数据 ， 一个Y对应多行
    *  数据配置，每一个配置就是一行。
    *  最后根据 X 上的 数据 遍历 生成 每一个Td
    * */
    renderYVOnY(){
        let trs ='';
        let tds;
        for(let i=0;i<this.vPivotData.vAxisY.length;i++) {
            /*
             renderY 要注意 1 : rowspan * factor
              空的点 不需要 render
            * */
            tds = this.renderYOnY(i);
            for (let j = 0; j < this.vCfg.values.length; j++) {
                /*
                * j==0 和上面的tds 是一行
                * j !=0 需要另起一行
                * */
                if (j != 0) {
                    trs += tmplTr.replace('{{html}}', tds);
                    tds = '';
                }
                // render 数据项目的 title
                tds +=  this.renderTd({},this.vCfg.values[j],'VTitle');
                for (let k = 0; k < this.vPivotData.vAxisX.length; k++) {
                    let item = this.vPivotData.vDataMatrix[i][k];
                    let pos = k+','+i+','+j;
                    tds += this.renderTd(item, this.vCfg.values[j], 'V', pos)
                }
                //最后一行
                if (j == this.vCfg.values.length - 1)
                    trs += tmplTr.replace('{{html}}', tds);
            }
        }
        return trs;
    }

    renderPivot(){
        if(this.vCfg.valuesOn=='Y'){
            this.$head.html(this.renderXOnY());
            this.$body.html(this.renderYVOnY());
        }else{
            this.$head.html(this.renderX());
            this.$body.html(this.renderYV());
        }
    }

    evFilter(e){
        let field = e.target.parentNode.getAttribute("data-code") ;
        let filterCfg ={
            data:this.vPivotData.getMapDataByField(field),
            select:this.vPivotData.getSelectByField(field),
            field,
            icon:this.vIcon,
            ok:this.filterOk.bind(this)
        };

        this.vFilter.show(filterCfg,this.$root ,$(e.target));
    }


    // 过滤后的回调函数
    filterOk(field,select,allChecked){
        if(allChecked==1)
            delete this.vPivotData.vFilterKeys[field];
        else
            this.vPivotData.addSelect(field,select);
        this.refresh();
    }

    evValueClick(e){
        if(this.vCfg.event && this.vCfg.event.OnValueClick){
            let code = e.currentTarget.getAttribute("data-code");
            let pos = code.split(',');
            let [x,y,z] = [pos[1],pos[0],pos[2]];
            this.vCfg.event.OnValueClick(this.vPivotData.vDataMatrix[x][y],this.vCfg.values[z]);
        }
    }

    evYClick(e){
        if(this.vCfg.event && this.vCfg.event.OnYClick){
            let code = e.currentTarget.getAttribute("data-code");
            let codeArray = code.split(',');
            this.vCfg.event.OnYClick(codeArray[codeArray.length-1],this.vCfg.keysY[codeArray.length-1]);
        }
    }

    evXClick(e){
        if(this.vCfg.event && this.vCfg.event.OnXClick){
            let code = e.currentTarget.getAttribute("data-code");
            let codeArray = code.split(',');
            this.vCfg.event.OnXClick(codeArray[codeArray.length-1],this.vCfg.keysX[codeArray.length-1]);
        }
    }

    setStyle(style){
        this.$root.attr('class',style);
    }

    saveCsv(fileName){
        saveAsCsv(fileName+'.csv',jsonToCsv(json));
    }

    saveXls(fileName){
        saveAsXmlXls(fileName+'.xls',new xmlTable().toXmlTable(this.$table));
    }
}